package edu.ccut.saturn.studio.component.model;

import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Node;


import edu.ccut.saturn.component.IParameterInfo;
import edu.ccut.saturn.studio.core.util.xml.SaturnW3CUtil;

/**
 * 
 * @author mn Date 2006-11-10 功能：属性xml文档定义
 * 
 */
public class ComponentModel {
	// private static final String ELEMENT_PROPERTY = "property";
	public static final String ELEMENT_COMPONENT = "component";
	// private static final String ELEMENT_BEAN = "bean";
	public static final String PARAMETERS_ELEMENT_PARAMETERS = "parameters";

	public static final String COMPONENT_ELEMENT_DESCRIPTION = "description";
	public static final String COMPONENT_ELEMENT_LOAD_START = "loadstart";
	public static final String PARAMETERS_ELEMENT_PARAMETER = "parameter";

	public static final String COMPONENT_ATTRIBUTE_PROJECTNAME = "projectname";
	public static final String COMPONENT_ATTRIBUTE_NAME = "name";
	public static final String COMPONENT_ATTRIBUTE_KEY = "key";
	public static final String COMPONENT_ATTRIBUTE_CLASS = "class";
	public static final String PARAMETER_ATTRIBUTE_NAME = "name";
	public static final String PARAMETER_ATTRIBUTE_ID = "id";
	public static final String PARAMETER_ATTRIBUTE_CLASSTYPE = "classType";
	public static final String PARAMETER_ATTRIBUTE_PASSINGTYPE = "passingType";
	public static final String PARAMETER_ELEMENT_SCOPE = "scope";
	public static final String PARAMETER_ELEMENT_VALUEKEY = "value-key";
	public static final String PARAMETER_ELEMENT_DESCRIPTION = "description";
	// private static final String ELEMENT_ATTRIBUTE_DATASOURCE = "dataSource";
	// private static final String PROPERTY_ATTRIBUTE_VALUE = "value";
	private Document document;
	private Component component;

	/**
	 * 构造函数
	 * 
	 * @param document
	 */
	public ComponentModel(Document document) {
		this.document = document;
	}

	public Document getDocument() {
		return document;
	}

	public Component getComponent() {
		if (this.component == null) {
			Node componentNode = SaturnW3CUtil.getFirstChildByName(
					this.getRootNode(), ELEMENT_COMPONENT);

			String projectName = SaturnW3CUtil.getNodeAttributeValue(
					componentNode, COMPONENT_ATTRIBUTE_PROJECTNAME);
			String key = SaturnW3CUtil.getNodeAttributeValue(componentNode,
					COMPONENT_ATTRIBUTE_KEY);
			String name = SaturnW3CUtil.getNodeAttributeValue(componentNode,
					COMPONENT_ATTRIBUTE_NAME);
			String clazz = SaturnW3CUtil.getNodeAttributeValue(componentNode,
					COMPONENT_ATTRIBUTE_CLASS);
			String description = SaturnW3CUtil.getChildNodeValue(componentNode,
					COMPONENT_ELEMENT_DESCRIPTION);
			String loadstart = SaturnW3CUtil.getChildNodeValue(componentNode,
					COMPONENT_ELEMENT_LOAD_START);

			component = new Component();

			component.setKey(key);
			component.setName(name);
			component.setClassStr(clazz);
			component.setDescription(description);
			component.setLoadStart(loadstart);
			component.setBundleSymbolicName(projectName);

			component.setParameterInfos(this.loadParameterInfo(componentNode));
			
			return component;
		}

		return null;
	}

	private List<IParameterInfo> loadParameterInfo(Node componentNode) {
		Node parametersNode = SaturnW3CUtil.getFirstChildByName(componentNode,
				PARAMETERS_ELEMENT_PARAMETERS);

		if (parametersNode != null) {
			List<Node> parameterNodes = SaturnW3CUtil.getChildrenByName(
					parametersNode, PARAMETERS_ELEMENT_PARAMETER);
			
			if (parameterNodes != null) {
				List<IParameterInfo> parameters = new ArrayList<IParameterInfo>();
				
				for (Node parameterNode : parameterNodes) {
					String id = SaturnW3CUtil.getNodeAttributeValue(parameterNode, PARAMETER_ATTRIBUTE_ID);
					String name = SaturnW3CUtil.getNodeAttributeValue(parameterNode, PARAMETER_ATTRIBUTE_NAME);
					String classType = SaturnW3CUtil.getNodeAttributeValue(parameterNode, PARAMETER_ATTRIBUTE_CLASSTYPE);
					String passingType = SaturnW3CUtil.getNodeAttributeValue(parameterNode, PARAMETER_ATTRIBUTE_PASSINGTYPE);
					
					String valueKey = SaturnW3CUtil.getChildNodeValue(parameterNode, PARAMETER_ELEMENT_VALUEKEY);
					String scope = SaturnW3CUtil.getChildNodeValue(parameterNode, PARAMETER_ELEMENT_SCOPE);
					String description = SaturnW3CUtil.getChildNodeValue(parameterNode, PARAMETER_ELEMENT_DESCRIPTION);
					
					Parameter parameterVO = new Parameter();
					parameterVO.setId(id);
					parameterVO.setName(name);
					parameterVO.setClassStr(classType);
					parameterVO.setPassingType(passingType);
					parameterVO.setValueKey(valueKey);
					parameterVO.setScope(Integer.parseInt(scope));
					parameterVO.setDescription(description);
					
					parameters.add(parameterVO);
				}
				
				return parameters;
			}
		}
		
		return null;
	}

	// ————————————————————————————————————获得的方法——————————————————————————————
	/**
	 * 得到component节点下属性的属性值
	 * 
	 * @param artValue，
	 * 
	 * @return
	 */
	public String getComponentAttribute(String attrValue) {
		Node componentNode = SaturnW3CUtil.getFirstChildByName(getRootNode(), ELEMENT_COMPONENT);

		String str = SaturnW3CUtil.getNodeAttributeValue(componentNode,
				attrValue);
		return str.trim();

	}

	/**
	 * 得到component节点下属性名为attrName的节点值
	 * 
	 * @param attrName，
	 * 
	 * @return
	 */
	public String getNodeValue(String attrName) {
		Node componentNode = SaturnW3CUtil.getFirstChildByName(getRootNode(), ELEMENT_COMPONENT);

		String str = SaturnW3CUtil.getChildNodeValue(componentNode, attrName);
		return str.trim();
	}

	/**
	 * 获得parameter的所有节点
	 * 
	 * @param
	 * 
	 * @return List<Node>
	 */
	public List<Node> getAllParameterValue() {
		Node componentNode = SaturnW3CUtil.getFirstChildByName(getRootNode(), ELEMENT_COMPONENT);

		Node nodeParameters = SaturnW3CUtil.getFirstChildByName(componentNode,
				PARAMETERS_ELEMENT_PARAMETERS);

		List<Node> parentList = SaturnW3CUtil.getChildrenByName(nodeParameters,
				PARAMETERS_ELEMENT_PARAMETER);

		return parentList;
	}

	/**
	 * 获得指定的parentparameterNode下的子节点value节点的值
	 * 
	 * @param
	 * 
	 * @return String
	 */
	public String getParameterArtValue(Node parameterNode, String childValue) {
		return SaturnW3CUtil.getChildNodeValue(parameterNode, childValue);
	}

	// ————————————————————————————————————增加的功能————————————————————————————；

	// 
	/**
	 * 添加一组parameter节点的参数节点
	 * 
	 * @param Parameter
	 * @return
	 */
	public void addParameter(Parameter parameterVO) {
		Node componentNode = SaturnW3CUtil.getFirstChildByName(getRootNode(), ELEMENT_COMPONENT);
		Node nodeParameters = SaturnW3CUtil.getFirstChildByName(componentNode,
				PARAMETERS_ELEMENT_PARAMETERS);
		List<Node> lengthList = SaturnW3CUtil.getChildrenByName(nodeParameters,
				PARAMETERS_ELEMENT_PARAMETER);

		Node newParrmeterNode = SaturnW3CUtil.createChildNode(nodeParameters,
				PARAMETERS_ELEMENT_PARAMETER, ""); // ""??

		parameterVO.setId(lengthList.size() + 1 + "");
		SaturnW3CUtil.createAttribute(newParrmeterNode, PARAMETER_ATTRIBUTE_ID,
				String.valueOf(parameterVO.getId()));
		SaturnW3CUtil.createAttribute(newParrmeterNode,
				PARAMETER_ATTRIBUTE_NAME, parameterVO.getName());// COMPONENT_ATTRIBUTE_NAME是否可以修改ELEMENT_ATTRIBUTE_NAME
		SaturnW3CUtil.createAttribute(newParrmeterNode,
				PARAMETER_ATTRIBUTE_CLASSTYPE, parameterVO.getClassStr());
		SaturnW3CUtil.createAttribute(newParrmeterNode,
				PARAMETER_ATTRIBUTE_PASSINGTYPE, parameterVO.getPassingType());

		SaturnW3CUtil.createChildNode(newParrmeterNode, PARAMETER_ELEMENT_SCOPE,
				parameterVO.getScope() + "");
		SaturnW3CUtil.createChildNode(newParrmeterNode,
				PARAMETER_ELEMENT_VALUEKEY, parameterVO.getValueKey());
		SaturnW3CUtil.createChildNode(newParrmeterNode,
				PARAMETER_ELEMENT_DESCRIPTION, parameterVO.getDescription());

		SaturnW3CUtil.format(newParrmeterNode.getParentNode());
		
		this.component.getParameterInfos().add(parameterVO);
	}

	// ——————————————————————————————————————修改——————————————————————————————————；

	private Node getParameterById(String id) {

		Node componentNode = SaturnW3CUtil.getFirstChildByName(getRootNode(), ELEMENT_COMPONENT);
		Node parametersNode = SaturnW3CUtil.getFirstChildByName(componentNode,
				PARAMETERS_ELEMENT_PARAMETERS);
		Node parameterNode = SaturnW3CUtil.getChildByNameAndAttribute(
				parametersNode, PARAMETERS_ELEMENT_PARAMETER,
				PARAMETER_ATTRIBUTE_ID, id);
		return parameterNode;
	}

	/**
	 * 修改componentNode节点下的子节点的值
	 * 
	 * @param String
	 * @return
	 * 
	 */
	public void updateComponentDescription(String newValue) {
		Node componentNode = SaturnW3CUtil.getFirstChildByName(getRootNode(), ELEMENT_COMPONENT);
		SaturnW3CUtil.setChildNodeValue(componentNode,
				COMPONENT_ELEMENT_DESCRIPTION, newValue);

		SaturnW3CUtil.format(getRootNode());
	}
	
	/**
	 * 修改componentNode节点下的加载启动子节点的值
	 * 
	 * @param String
	 * @return
	 * 
	 */
	public void updateComponentLoadStart(String newValue) {
		Node componentNode = SaturnW3CUtil.getFirstChildByName(getRootNode(), ELEMENT_COMPONENT);
		SaturnW3CUtil.setChildNodeValue(componentNode,
				COMPONENT_ELEMENT_LOAD_START, newValue);
		
		SaturnW3CUtil.format(getRootNode());
	}


	/**
	 * 修改componentNode属�性
	 * 
	 * @param String
	 * @return
	 * 
	 */
	public void updateComponentAttribute(String attrName, String newValue) {
		Node componentNode = SaturnW3CUtil.getFirstChildByName(this.getRootNode(),
				ELEMENT_COMPONENT);
		SaturnW3CUtil.createAttribute(componentNode, attrName, newValue);

		SaturnW3CUtil.format(getRootNode());
	}

	private Node getRootNode() {
		return this.document.getDocumentElement();
	}

	/**
	 * 修改parameter节点的属性值 (updateNodeValue分出来的子节点值修改)
	 * 
	 * @param String
	 *            id String attrName String newValue
	 * @return
	 * 
	 */
	public void updateParameterValue(String id, String attrName, String newValue) {
		Node parameterNode = getParameterById(id);

		SaturnW3CUtil.createAttribute(parameterNode, attrName, newValue);

		SaturnW3CUtil.format(getRootNode());
	}

	/**
	 * 修改parameter的子节点的值 (updateNodeValue分出来的节点的属性值修改)
	 * 
	 * @param String
	 *            id String childName String newChildValue
	 * @return
	 * 
	 */
	public void updateParameterChildValue(String id, String childName,
			String newChildValue) {
		SaturnW3CUtil.setChildNodeValue(getParameterById(id), childName,
				newChildValue);

		SaturnW3CUtil.format(getParameterById(id).getParentNode());
	}

	/**
	 * 修改parameter的属性和节点的值
	 * 
	 * @param Parameter
	 * @return
	 * 
	 */
	public void updatepParameterValue(Parameter parameterVO) {

		Node parameterNode = this.getParameterById(parameterVO.getId() + "");

		SaturnW3CUtil.createAttribute(parameterNode, COMPONENT_ATTRIBUTE_NAME,
				parameterVO.getName());
		SaturnW3CUtil.createAttribute(parameterNode,
				PARAMETER_ATTRIBUTE_CLASSTYPE, parameterVO.getClassStr());
		SaturnW3CUtil.createAttribute(parameterNode,
				PARAMETER_ATTRIBUTE_PASSINGTYPE, parameterVO.getPassingType());

		SaturnW3CUtil.setChildNodeValue(parameterNode, PARAMETER_ELEMENT_VALUEKEY,
				parameterVO.getValueKey());
		SaturnW3CUtil.setChildNodeValue(parameterNode, PARAMETER_ELEMENT_SCOPE,
				parameterVO.getScope() + "");
		SaturnW3CUtil.setChildNodeValue(parameterNode,
				COMPONENT_ELEMENT_DESCRIPTION, parameterVO.getDescription());
//		SaturnW3CUtil.setChildNodeValue(parameterNode,
//				COMPONENT_ELEMENT_LOAD_START, parameterVO.getLoadstart());
//		

		SaturnW3CUtil.format(parameterNode.getParentNode());
	}

	// ——————————————————————————删除————————————————————————————
	/**
	 * 移除指定的parameter的节点
	 * 
	 * @param int
	 *            id
	 * @return
	 * 
	 */
	public void removeParameterNode(int id) {
		Node removedNode = this.getParameterById(id + "");

		Node parametersNode = removedNode.getParentNode();

		SaturnW3CUtil.removeChildren(removedNode);
		parametersNode.removeChild(removedNode);

		List<Node> paramerterNodes = SaturnW3CUtil.getChildrenByName(
				parametersNode, PARAMETERS_ELEMENT_PARAMETER);

		int i = 1;
		for (Node parameterNode : paramerterNodes) {
			parameterNode.getAttributes().getNamedItem(PARAMETER_ATTRIBUTE_ID)
					.setNodeValue((i++) + "");
		}

		SaturnW3CUtil.format(parametersNode);
	}

//	/**
//	 * 移动parameter节点
//	 * 
//	 * @param List
//	 *            <ParameterVO> parameters
//	 */
//	public void moveParameter(List<ParameterVO> parameters) {
//		Node componentNode = SaturnW3CUtil.getFirstChildByName(getRootNode(), ELEMENT_COMPONENT);
//		Node parametersNode = SaturnW3CUtil.getFirstChildByName(componentNode,
//				PARAMETERS_ELEMENT_PARAMETERS);
//		SaturnW3CUtil.removeChildren(parametersNode);
//
//		if (parameters != null) {
//			for (ParameterVO parameterVO : parameters) {
//				addParameter(parameterVO);
//			}
//		}
//
//		SaturnW3CUtil.format(parametersNode.getParentNode());
//	}

	/**
	 * 获得getProjectName
	 * 
	 * @return String
	 */
	public String getProjectName() {
		Node componentNode = SaturnW3CUtil.getFirstChildByName(this.getRootNode(),
				ELEMENT_COMPONENT);
		return SaturnW3CUtil.getNodeAttributeValue(componentNode,
				COMPONENT_ATTRIBUTE_PROJECTNAME);
	}
	
	/**
	 * 新添加循环更新parameter节点
	 * 
	 * @param parameters
	 */
	
	public void updatepParameterValue1(List<Parameter> parameters) {
		Node componentNode = SaturnW3CUtil.getFirstChildByName(getRootNode(), ELEMENT_COMPONENT);

		Node nodeParameters = SaturnW3CUtil.getFirstChildByName(componentNode,
				PARAMETERS_ELEMENT_PARAMETERS);
		
		for (Parameter parameterVO : parameters ) {
			
		
			Node parameterNode = this.getParameterById(parameterVO.getId() + "");
	
			SaturnW3CUtil.createAttribute(parameterNode, COMPONENT_ATTRIBUTE_NAME,
					parameterVO.getName());
			SaturnW3CUtil.createAttribute(parameterNode,
					PARAMETER_ATTRIBUTE_CLASSTYPE, parameterVO.getClassStr());
			SaturnW3CUtil.createAttribute(parameterNode,
					PARAMETER_ATTRIBUTE_PASSINGTYPE, parameterVO.getPassingType());
	
			SaturnW3CUtil.setChildNodeValue(parameterNode, PARAMETER_ELEMENT_VALUEKEY,
					parameterVO.getValueKey());
			SaturnW3CUtil.setChildNodeValue(parameterNode, PARAMETER_ELEMENT_SCOPE,
					parameterVO.getScope() + "");
			SaturnW3CUtil.setChildNodeValue(parameterNode,
					COMPONENT_ELEMENT_DESCRIPTION, parameterVO.getDescription());
//			SaturnW3CUtil.setChildNodeValue(parameterNode,
//					COMPONENT_ELEMENT_LOAD_START, parameterVO.getLoadstart());
		
		}
		SaturnW3CUtil.format(nodeParameters.getParentNode());
	}
	
}